package com.dmagic.cms.service.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.persistence.RollbackException;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dmagic.cms.bean.HeatMapFormBean;
import com.dmagic.cms.common.dao.CommonDao;
import com.dmagic.cms.common.exception.ServiceException;
import com.dmagic.cms.common.exception.ValidateException;
import com.dmagic.cms.common.query.PageUtil;
import com.dmagic.cms.common.service.CommonService;
import com.dmagic.cms.common.util.ListUtil;
import com.dmagic.cms.common.util.reflection.BeanUtil;
import com.dmagic.cms.dao.HeatMapDao;
import com.dmagic.cms.dao.LinkedHeatMapDao;
import com.dmagic.cms.dao.UploadFileInfoDao;
import com.dmagic.cms.entity.HeatMap;
import com.dmagic.cms.entity.LinkedHeatMap;
import com.dmagic.cms.entity.News;
import com.dmagic.cms.entity.Product;
import com.dmagic.cms.entity.SuccessfulCase;
import com.dmagic.cms.entity.UploadFileInfo;
import com.dmagic.cms.service.HeatMapService;
import com.dmagic.cms.service.NewsService;
import com.dmagic.cms.service.ProductService;
import com.dmagic.cms.service.SuccessfulCaseService;
import com.google.common.collect.Lists;

/**
 * @author songlin.li
 * 
 */
@Service
@Transactional(readOnly = true, rollbackFor = { ValidateException.class, RollbackException.class })
public class HeatMapServiceImpl extends CommonService<HeatMap> implements HeatMapService {

	@Autowired
	private UploadFileInfoDao uploadFileInfoDao;

	@Autowired
	private LinkedHeatMapDao linkedHeatMapDao;

	@Autowired
	private HeatMapDao heatMapDao;

	@Autowired
	private NewsService newsService;

	@Autowired
	private ProductService productService;

	@Autowired
	private SuccessfulCaseService successfulCaseService;

	@Override
	protected CommonDao<HeatMap, Serializable> getCommonDao() {
		return (CommonDao) heatMapDao;
	}

	@Transactional(readOnly = false)
	@Override
	public void setLinkedHeatMap(LinkedHeatMap linkedHeatMap) throws ServiceException {
		List<LinkedHeatMap> hotPictures = linkedHeatMapDao.findLinkedHeatMapBy(
				linkedHeatMap.getLinkedHeatMapLinkedId(), linkedHeatMap.getLinkedHeatMapType());
		if (ListUtil.isNotEmpty(hotPictures)) {
			LinkedHeatMap h = hotPictures.get(0);
			h.setLinkedHeatMapStatus(linkedHeatMap.getLinkedHeatMapStatus());
			linkedHeatMapDao.saveEntity(h);
			if (!h.getLinkedHeatMapStatus()) {
				List<HeatMap> heatMaps = heatMapDao.getHeatMapByLinkedHeatMapId(h.getLinkedHeatMapId());
				for (HeatMap heatMap : heatMaps) {
					heatMap.setHeatMapStatus(false);
				}
				saveHeatMaps(heatMaps);
			}
		} else {
			linkedHeatMapDao.saveEntity(linkedHeatMap);
		}
	}

	@Override
	public List<HeatMapFormBean> findUploadFileInfoImage() throws ServiceException {
		List<LinkedHeatMap> linkedHeatMaps = linkedHeatMapDao.findBy("linkedHeatMapStatus", true);
		List<HeatMapFormBean> result = Lists.newLinkedList();
		for (LinkedHeatMap linkedHeatMap : linkedHeatMaps) {
			Long uploadFileSetInfoId = null;
			String title = "";
			switch (linkedHeatMap.getLinkedHeatMapType()) {
			case 0:
				News news = newsService.getNews(linkedHeatMap.getLinkedHeatMapLinkedId());
				uploadFileSetInfoId = news.getUploadFileSetInfoId();
				title = news.getNewsTitle();
				break;
			case 1:
				Product product = productService.getProduct(linkedHeatMap.getLinkedHeatMapLinkedId());
				uploadFileSetInfoId = product.getUploadFileSetInfoId();
				title = product.getProductName();
				break;
			case 2:
				SuccessfulCase successfulCase = successfulCaseService.getSuccessfulCase(linkedHeatMap
						.getLinkedHeatMapLinkedId());
				uploadFileSetInfoId = successfulCase.getUploadFileSetInfoId();
				title = successfulCase.getSuccessfulCaseName();
				break;
			default:
				break;
			}
			if (uploadFileSetInfoId != null) {
				List<UploadFileInfo> hotImages = uploadFileInfoDao
						.getUploadFileInfoListByUploadFileSetInfoId(uploadFileSetInfoId);
				for (UploadFileInfo uploadFileInfo : hotImages) {
					HeatMap heatMap = heatMapDao.findUniqueBy("uploadFileInfoId",
							uploadFileInfo.getUploadFileInfoId());
					HeatMapFormBean bean = new HeatMapFormBean();
					try {
						PropertyUtils.copyProperties(bean, uploadFileInfo);
						PropertyUtils.copyProperties(bean, linkedHeatMap);
						if (heatMap != null) {
							heatMapDao.evict(heatMap);
							if (heatMap.getFileInfoId() != null) {
								UploadFileInfo fileInfo = uploadFileInfoDao.getEntityById(heatMap
										.getFileInfoId());
								PropertyUtils.copyProperties(bean, fileInfo);
							}
							PropertyUtils.copyProperties(bean, heatMap);
						}
					} catch (Exception e) {
						throw new ServiceException(e);
					}
					bean.setHeatMapTitle(title);
					result.add(bean);
				}
			}
		}
		return result;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.dmagic.cms.service.HeatMapService#searchHeatMap(com.dmagic.cms.common
	 *      .query.PageUtil)
	 */
	public List<HeatMapFormBean> searchHeatMap(PageUtil<Map> pageUtil) throws ServiceException {
		List<HeatMapFormBean> result = Lists.newLinkedList();
		try {
			heatMapDao.searchHeatMaps(pageUtil);
			List<Map> lists = pageUtil.getResult();
			for (Map map : lists) {
				HeatMapFormBean bean = BeanUtil.mapToBean(map, HeatMapFormBean.class);
				if (bean.getFileInfoId() != null) {
					UploadFileInfo fileInfo = uploadFileInfoDao.getEntityById(bean.getFileInfoId());
					//PropertyUtils.copyProperties(bean, fileInfo);
					bean.setFileName(fileInfo.getFileName());
				}
				result.add(bean);
			}
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		return result;
	}

	@Transactional(readOnly = false)
	@Override
	public void saveHeatMaps(List<HeatMap> heatMaps) throws ServiceException {
		for (HeatMap heatMap : heatMaps) {
			if (heatMap.getHeatMapId() == null) {
				heatMapDao.saveEntity(heatMap);
			} else {
				heatMapDao.merge(heatMap);
			}
		}
	}

	@Override
	public HeatMap getHeatMap(Long heatMapId) {
		return heatMapDao.getEntityById(heatMapId);
	}

	@Transactional(readOnly = false)
	@Override
	public void deleteLinkedHeatMapByLinkedIdAndType(Long linkedHeatMapLinkedId, Integer linkedHeatMapType) {
		List<LinkedHeatMap> linkHeatMap = linkedHeatMapDao.findLinkedHeatMapBy(linkedHeatMapLinkedId,
				linkedHeatMapType);
		for (LinkedHeatMap linkedHeatMap : linkHeatMap) {
			List<HeatMap> heatMaps = heatMapDao.getHeatMapByLinkedHeatMapId(linkedHeatMap
					.getLinkedHeatMapId());
			for (HeatMap heatMap : heatMaps) {
				heatMapDao.deleteEntityById(heatMap.getHeatMapId());
			}
			linkedHeatMapDao.deleteEntityById(linkedHeatMap.getLinkedHeatMapId());
		}
	}

	@Override
	public List queryHeatMapInfo(Long languageId) {
		return heatMapDao.queryHeatMapInfo(languageId);
	}
}
